package com.train.common.utils.jwt;

import cn.hutool.json.JSONObject;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTPayload;
import com.train.common.utils.date.LocalDateTimeUtils;
import com.train.common.utils.exception.ExceptionUtils;
import com.train.common.utils.resource.ResourceUtils;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class JwtUtils {

    /**
     * 签名使用HS256算法
     */
    private static final String KEY = ResourceUtils.readKey("HS256_key");

    /**
     * 通过公钥和密钥生成token
     * @param payloads
     * @return
     */
    public static String create(Map<String, ?> payloads) {
        LocalDateTime now = LocalDateTimeUtils.getNow();
        return JWT.create()
                .setNotBefore(LocalDateTimeUtils.toDate(now)) //生效时间
                .setExpiresAt(LocalDateTimeUtils.toDate(now.plusHours(24))) //过期时间
                .setIssuedAt(LocalDateTimeUtils.toDate(now)) //签发时间
                .addPayloads(payloads)
                .setKey(KEY.getBytes())
                .sign();
    }

    /**
     * 解析token
     * @param token
     * @return
     */
    public static Map<String, ?> parse(String token) {
        if (!validate(token)) {
            return new HashMap<>();
        }
        JWT jwt = JWT.of(token);
        JSONObject payloads = jwt.getPayloads();
        payloads.remove(JWTPayload.EXPIRES_AT);
        payloads.remove(JWTPayload.ISSUED_AT);
        payloads.remove(JWTPayload.NOT_BEFORE);
        return payloads;
    }

    /**
     * 验证签名有效性和过期时间
     * @param token
     * @return
     */
    public static boolean validate(String token) {
        try {
            return JWT.of(token).setKey(KEY.getBytes()).validate(0);
        } catch (Exception e) {
            log.error("token验证失败: {}", ExceptionUtils.getExpMsg(e));
            return false;
        }
    }

    public static void main(String[] args) {
        String token = JwtUtils.create(Map.of("name", "zhangsan"));
        System.out.println(token);
        System.out.println(validate(token));
        System.out.println(JwtUtils.parse(token));
    }
}
